#ifndef USER32_H
#define USER32_H
#include "minwin.h"

#ifdef UNICODE
#define MessageBox MessageBoxW
#define LoadCursor LoadCursorW
#define RegisterClassEx RegisterClassExW
#define SetWindowLongPtr SetWindowLongPtrW
#define GetWindowLongPtr GetWindowLongPtrW
#define DefWindowProc DefWindowProcW
#define CreateWindowEx CreateWindowExW
#define PeekMessage PeekMessageW
#define DispatchMessage DispatchMessageW

#else
#define MessageBox MessageBoxA
#define LoadCursor LoadCursorA
#define RegisterClassEx RegisterClassExA
#define SetWindowLongPtr SetWindowLongPtrA
#define GetWindowLongPtr GetWindowLongPtrA
#define DefWindowProc DefWindowProcA
#define CreateWindowEx CreateWindowExA
#define PeekMessage PeekMessageA
#define DispatchMessage DispatchMessageA
#endif

#define IDC_APPSTARTING MAKEINTRESOURCE(32650)
#define IDC_ARROW MAKEINTRESOURCE(32512)
#define IDC_CROSS MAKEINTRESOURCE(32515)
#define IDC_HAND MAKEINTRESOURCE(32649)
#define IDC_HELP MAKEINTRESOURCE(32651)
#define IDC_IBEAM MAKEINTRESOURCE(32513)
#define IDC_ICON MAKEINTRESOURCE(32641)
#define IDC_NO MAKEINTRESOURCE(32648)
#define IDC_SIZE MAKEINTRESOURCE(32640)
#define IDC_SIZEALL MAKEINTRESOURCE(32646)
#define IDC_SIZENESW MAKEINTRESOURCE(32643)
#define IDC_SIZENS MAKEINTRESOURCE(32645)
#define IDC_SIZENWSE MAKEINTRESOURCE(32642)
#define IDC_SIZEWE MAKEINTRESOURCE(32644)
#define IDC_UPARROW MAKEINTRESOURCE(32516)
#define IDC_WAIT MAKEINTRESOURCE(32514)

#define GWL_EXSTYLE (-20)
#define GWLP_HINSTANCE (-6)
#define GWLP_HWNDPARENT (-8)
#define GWLP_ID (-12)
#define GWL_STYLE (-16)
#define GWLP_USERDATA (-21)
#define GWLP_WNDPROC (-4)

#define DWLP_MSGRESULT 0
#define DWLP_DLGPROG 8
#define DWLP_USER 16

#define MB_OK 0
#define MB_ABORTRETRYIGNORE 0x2
#define MB_CANCELTRYCONTINUE
#define MB_HELP 0x4000
#define MB_OKCANCEL 0x1
#define MB_RETRYCANCEL 0x5
#define MB_YESNO 0x4
#define MB_YESNOCANCEL 0x3
#define MB_ICONEXCLAMATION 0x30
#define MB_ICONWARNING 0x30
#define MB_ICONINFORMATION 0x40
#define MB_ICONASTERISK 0x40
#define MB_ICONQUESTION 0x20
#define MB_ICONSTOP 0x10
#define MB_ICONERROR 0x10
#define MB_ICONHAND 0x10
#define MB_APPLMODAL 0
#define MB_SYSTEMMODAL 0x1000
#define MB_TASKMODAL 0x2000
#define MB_DEFAULT_DESKTOP_ONLY 0x20000
#define MB_RIGHT 0x80000
#define MB_RTLREADING 0x100000
#define MB_SETFOREGROUND 0x10000
#define MB_TOPMOST 0x40000
#define MB_SERVICE_NOTIFICAITON 0x200000

#define CS_VREDRAW             0x1
#define CS_HREDRAW             0x2
#define CS_DBLCLKS             0x8
#define CS_OWNDC              0x20
#define CS_CLASSDC            0x40
#define CS_PARENTDC           0x80
#define CS_NOCLOSE           0x200
#define CS_SAVEBITS          0x800
#define CS_BYTEALIGNCLIENT  0x1000
#define CS_BYTEALIGNWINDOW  0x2000
#define CS_GLOBALCLASS      0x4000
#define CS_IME             0x10000
#define CS_DROPSHADOW      0x20000

#define SW_HIDE 0
#define SW_SHOWNORMAL 1
#define SW_NORMAL 1
#define SW_SHOWMINIMIZED 2
#define SW_SHOWMAXIMIZED 3
#define SW_MAXIMIZE 3
#define SW_SHOWNOACTIVATE 4
#define SW_SHOW 5
#define SW_MINIMIZE 6
#define SW_SHOWMINNOACTIVE 7
#define SW_SHOWNA 8
#define SW_RESTORE 9
#define SW_SHOWDEFAULT 10
#define SW_FORCEMINIMIZE 11
#define SW_MAX 11

#define CW_USEDEFAULT (0x80000000)

#define WS_OVERLAPPED         (0x0)
#define WS_MAXIMIZEBOX    (0x10000)
#define WS_TABSTOP        (0x10000)
#define WS_MINIMIZEBOX    (0x20000)
#define WS_GROUP          (0x20000)
#define WS_THICKFRAME (    0x40000)
#define WS_SYSMENU        (0x80000)
#define WS_HSCROLL       (0x100000)
#define WS_VSCROLL       (0x200000)
#define WS_DLGFRAME      (0x400000)
#define WS_BORDER        (0x800000)
#define WS_CAPTION       (0xC00000)
#define WS_MAXIMIZE     (0x1000000)
#define WS_CLIPCHILDREN (0x2000000)
#define WS_CLIPSIBLINGS (0x4000000)
#define WS_DISABLED     (0x8000000)
#define WS_VISIBLE     (0x10000000)
#define WS_MINIMIZE    (0x20000000)
#define WS_CHILD       (0x40000000)
#define WS_POPUP       (0x80000000)
#define WS_TILED             WS_OVERLAPPED
#define WS_ICONIC            WS_MINIMIZE
#define WS_SIZEBOX           WS_THICKFRAME
#define WS_TILEDWINDOW       WS_OVERLAPPEDWINDOW
#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
#define WS_POPUPWINDOW (WS_POPUP | WS_BORDER | WS_SYSMENU)
#define WS_CHILDWINDOW (WS_CHILD)
#define WS_EX_LEFT                     (0x0)
#define WS_EX_LTRREADING               (0x0)
#define WS_EX_RIGHTSCROLLBAR           (0x0)
#define WS_EX_DLGMODALFRAME            (0x1)
#define WS_EX_NOPARENTNOTIFY           (0x4)
#define WS_EX_TOPMOST                  (0x8)
#define WS_EX_ACCEPTFILES             (0x10)
#define WS_EX_TRANSPARENT             (0x20)
#define WS_EX_MDICHILD                (0x40)
#define WS_EX_TOOLWINDOW              (0x80)
#define WS_EX_WINDOWEDGE             (0x100)
#define WS_EX_CLIENTEDGE             (0x200)
#define WS_EX_CONTEXTHELP            (0x400)
#define WS_EX_RIGHT                 (0x1000)
#define WS_EX_RTLREADING            (0x2000)
#define WS_EX_LEFTSCROLLBAR         (0x4000)
#define WS_EX_CONTROLPARENT        (0x10000)
#define WS_EX_STATICEDGE           (0x20000)
#define WS_EX_APPWINDOW            (0x40000)
#define WS_EX_LAYERED              (0x80000)
#define WS_EX_NOINHERITLAYOUT     (0x100000)
#define WS_EX_NOREDIRECTIONBITMAP (0x200000)
#define WS_EX_LAYOUTRTL           (0x400000)
#define WS_EX_COMPOSITED         (0x2000000)
#define WS_EX_NOACTIVATE         (0x8000000)
#define WS_EX_OVERLAPPEDWINDOW   (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE)
#define WS_EX_PALETTEWINDOW      (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST)

#define PM_NOREMOVE 0
#define PM_REMOVE 1
#define PM_NOYIELD 2

#define MK_LBUTTON   0x1
#define MK_RBUTTON   0x2
#define MK_SHIFT     0x4
#define MK_CONTROL   0x8
#define MK_MBUTTON  0x10
#define MK_XBUTTON1 0x20
#define MK_XBUTTON2 0x40

#define WM_NULL 0x0000
#define WM_CREATE 0x0001
#define WM_DESTROY 0x0002
#define WM_MOVE 0x0003
#define WM_SIZE 0x0005
#define WM_ACTIVATE 0x0006

#define WM_SETFOCUS 0x0007
#define WM_KILLFOCUS 0x0008
#define WM_ENABLE 0x000A
#define WM_SETREDRAW 0x000B
#define WM_SETTEXT 0x000C
#define WM_GETTEXT 0x000D
#define WM_GETTEXTLENGTH 0x000E
#define WM_PAINT 0x000F
#define WM_CLOSE 0x0010
#define WM_QUERYENDSESSION 0x0011
#define WM_QUERYOPEN 0x0013
#define WM_ENDSESSION 0x0016
#define WM_QUIT 0x0012
#define WM_ERASEBKGND 0x0014
#define WM_SYSCOLORCHANGE 0x0015
#define WM_SHOWWINDOW 0x0018
#define WM_WININICHANGE 0x001A
#define WM_SETTINGCHANGE WM_WININICHANGE
#define WM_DEVMODECHANGE 0x001B
#define WM_ACTIVATEAPP 0x001C
#define WM_FONTCHANGE 0x001D
#define WM_TIMECHANGE 0x001E
#define WM_CANCELMODE 0x001F
#define WM_SETCURSOR 0x0020
#define WM_MOUSEACTIVATE 0x0021
#define WM_CHILDACTIVATE 0x0022
#define WM_QUEUESYNC 0x0023
#define WM_GETMINMAXINFO 0x0024

#define WM_PAINTICON 0x0026
#define WM_ICONERASEBKGND 0x0027
#define WM_NEXTDLGCTL 0x0028
#define WM_SPOOLERSTATUS 0x002A
#define WM_DRAWITEM 0x002B
#define WM_MEASUREITEM 0x002C
#define WM_DELETEITEM 0x002D
#define WM_VKEYTOITEM 0x002E
#define WM_CHARTOITEM 0x002F
#define WM_SETFONT 0x0030
#define WM_GETFONT 0x0031
#define WM_SETHOTKEY 0x0032
#define WM_GETHOTKEY 0x0033
#define WM_QUERYDRAGICON 0x0037
#define WM_COMPAREITEM 0x0039
#define WM_GETOBJECT 0x003D
#define WM_COMPACTING 0x0041
#define WM_COMMNOTIFY 0x0044
#define WM_WINDOWPOSCHANGING 0x0046
#define WM_WINDOWPOSCHANGED 0x0047
#define WM_POWER 0x0048

#define PWR_OK 1
#define PWR_FAIL (-1)
#define PWR_SUSPENDREQUEST 1
#define PWR_SUSPENDRESUME 2
#define PWR_CRITICALRESUME 3

#define WM_COPYDATA 0x004A
#define WM_CANCELJOURNAL 0x004B

#define WM_NOTIFY 0x004E
#define WM_INPUTLANGCHANGEREQUEST 0x0050
#define WM_INPUTLANGCHANGE 0x0051
#define WM_TCARD 0x0052
#define WM_HELP 0x0053
#define WM_USERCHANGED 0x0054
#define WM_NOTIFYFORMAT 0x0055

#define WM_CONTEXTMENU 0x007B
#define WM_STYLECHANGING 0x007C
#define WM_STYLECHANGED 0x007D
#define WM_DISPLAYCHANGE 0x007E
#define WM_GETICON 0x007F
#define WM_SETICON 0x0080

#define WM_NCCREATE 0x0081
#define WM_NCDESTROY 0x0082
#define WM_NCCALCSIZE 0x0083
#define WM_NCHITTEST 0x0084
#define WM_NCPAINT 0x0085
#define WM_NCACTIVATE 0x0086
#define WM_GETDLGCODE 0x0087
#define WM_SYNCPAINT 0x0088
#define WM_NCMOUSEMOVE 0x00A0
#define WM_NCLBUTTONDOWN 0x00A1
#define WM_NCLBUTTONUP 0x00A2
#define WM_NCLBUTTONDBLCLK 0x00A3
#define WM_NCRBUTTONDOWN 0x00A4
#define WM_NCRBUTTONUP 0x00A5
#define WM_NCRBUTTONDBLCLK 0x00A6
#define WM_NCMBUTTONDOWN 0x00A7
#define WM_NCMBUTTONUP 0x00A8
#define WM_NCMBUTTONDBLCLK 0x00A9

#define WM_NCXBUTTONDOWN 0x00AB
#define WM_NCXBUTTONUP 0x00AC
#define WM_NCXBUTTONDBLCLK 0x00AD
#define WM_INPUT_DEVICE_CHANGE 0x00fe
#define WM_INPUT 0x00FF
#define WM_KEYFIRST 0x0100
#define WM_KEYDOWN 0x0100
#define WM_KEYUP 0x0101
#define WM_CHAR 0x0102
#define WM_DEADCHAR 0x0103
#define WM_SYSKEYDOWN 0x0104
#define WM_SYSKEYUP 0x0105
#define WM_SYSCHAR 0x0106
#define WM_SYSDEADCHAR 0x0107
#define WM_UNICHAR 0x0109
#define WM_KEYLAST 0x0109
#define UNICODE_NOCHAR 0xFFFF
#define WM_IME_STARTCOMPOSITION 0x010D
#define WM_IME_ENDCOMPOSITION 0x010E
#define WM_IME_COMPOSITION 0x010F
#define WM_IME_KEYLAST 0x010F
#define WM_INITDIALOG 0x0110
#define WM_COMMAND 0x0111
#define WM_SYSCOMMAND 0x0112
#define WM_TIMER 0x0113
#define WM_HSCROLL 0x0114
#define WM_VSCROLL 0x0115
#define WM_INITMENU 0x0116
#define WM_INITMENUPOPUP 0x0117
#define WM_MENUSELECT 0x011F
#define WM_GESTURE 0x0119
#define WM_GESTURENOTIFY 0x011A
#define WM_MENUCHAR 0x0120
#define WM_ENTERIDLE 0x0121
#define WM_MENURBUTTONUP 0x0122
#define WM_MENUDRAG 0x0123
#define WM_MENUGETOBJECT 0x0124
#define WM_UNINITMENUPOPUP 0x0125
#define WM_MENUCOMMAND 0x0126
#define WM_CHANGEUISTATE 0x0127
#define WM_UPDATEUISTATE 0x0128
#define WM_QUERYUISTATE 0x0129

#define WM_DEVICECHANGE 0x219

#define WM_MDICREATE 0x220
#define WM_MDIDESTROY 0x221
#define WM_MDIACTIVATE 0x222
#define WM_MDIRESTORE 0x223
#define WM_MDINEXT 0x224
#define WM_MDIMAXIMIZE 0x225
#define WM_MDITILE 0x226
#define WM_MDICASCADE 0x227
#define WM_MDIICONARRANGE 0x228
#define WM_MDIGETACTIVE 0x229

#define WM_MDISETMENU 0x230
#define WM_ENTERSIZEMOVE 0x231
#define WM_EXITSIZEMOVE 0x232
#define WM_DROPFILES 0x233
#define WM_MDIREFRESHMENU 0x234
#define WM_POINTERDEVICECHANGE 0x238
#define WM_POINTERDEVICEINRANGE 0x239
#define WM_POINTERDEVICEOUTOFRANGE 0x23a
#define WM_TOUCH 0x240
#define WM_NCPOINTERUPDATE 0x241
#define WM_NCPOINTERDOWN 0x242
#define WM_NCPOINTERUP 0x243
#define WM_POINTERUPDATE 0x245
#define WM_POINTERDOWN 0x246
#define WM_POINTERUP 0x247
#define WM_POINTERENTER 0x249
#define WM_POINTERLEAVE 0x24a
#define WM_POINTERACTIVATE 0x24b
#define WM_POINTERCAPTURECHANGED 0x24c
#define WM_TOUCHHITTESTING 0x24d
#define WM_POINTERWHEEL 0x24e
#define WM_POINTERHWHEEL 0x24f

#define WM_IME_SETCONTEXT 0x281
#define WM_IME_NOTIFY 0x282
#define WM_IME_CONTROL 0x283
#define WM_IME_COMPOSITIONFULL 0x284
#define WM_IME_SELECT 0x285
#define WM_IME_CHAR 0x286
#define WM_IME_REQUEST 0x288
#define WM_IME_KEYDOWN 0x290
#define WM_IME_KEYUP 0x291

#define WM_MOUSEHOVER 0x2A1
#define WM_MOUSELEAVE 0x2A3
#define WM_NCMOUSEHOVER 0x2A0
#define WM_NCMOUSELEAVE 0x2A2
#define WM_WTSSESSION_CHANGE 0x2B1
#define WM_TABLET_FIRST 0x2c0
#define WM_TABLET_LAST 0x2df
#define WM_CUT 0x300
#define WM_COPY 0x301
#define WM_PASTE 0x302
#define WM_CLEAR 0x303
#define WM_UNDO 0x304
#define WM_RENDERFORMAT 0x305
#define WM_RENDERALLFORMATS 0x306
#define WM_DESTROYCLIPBOARD 0x307
#define WM_DRAWCLIPBOARD 0x308
#define WM_PAINTCLIPBOARD 0x309
#define WM_VSCROLLCLIPBOARD 0x30A
#define WM_SIZECLIPBOARD 0x30B
#define WM_ASKCBFORMATNAME 0x30C
#define WM_CHANGECBCHAIN 0x30D
#define WM_HSCROLLCLIPBOARD 0x30E
#define WM_QUERYNEWPALETTE 0x30F
#define WM_PALETTEISCHANGING 0x310
#define WM_PALETTECHANGED 0x311
#define WM_HOTKEY 0x312
#define WM_PRINT 0x317
#define WM_PRINTCLIENT 0x318
#define WM_APPCOMMAND 0x319
#define WM_THEMECHANGED 0x31A
#define WM_CLIPBOARDUPDATE 0x31d
#define WM_DWMCOMPOSITIONCHANGED 0x31e
#define WM_DWMNCRENDERINGCHANGED 0x31f
#define WM_DWMCOLORIZATIONCOLORCHANGED 0x320
#define WM_DWMWINDOWMAXIMIZEDCHANGE 0x321
#define WM_DWMSENDICONICTHUMBNAIL 0x323
#define WM_DWMSENDICONICLIVEPREVIEWBITMAP 0x326
#define WM_GETTITLEBARINFOEX 0x33f
#define WM_HANDHELDFIRST 0x358
#define WM_HANDHELDLAST 0x35F
#define WM_AFXFIRST 0x360
#define WM_AFXLAST 0x37F
#define WM_PENWINFIRST 0x380
#define WM_PENWINLAST 0x38F
#define WM_APP 0x8000
#define WM_USER 0x400
#define WM_PARENTNOTIFY 0x210
#define WM_ENTERMENULOOP 0x211
#define WM_EXITMENULOOP 0x212
#define WM_NEXTMENU 0x213
#define WM_SIZING 0x214
#define WM_CAPTURECHANGED 0x215
#define WM_MOVING 0x216
#define WM_POWERBROADCAST 0x218
#define WM_CTLCOLORMSGBOX 0x132
#define WM_CTLCOLOREDIT 0x133
#define WM_CTLCOLORLISTBOX 0x134
#define WM_CTLCOLORBTN 0x135
#define WM_CTLCOLORDLG 0x136
#define WM_CTLCOLORSCROLLBAR 0x137
#define WM_CTLCOLORSTATIC 0x138

#define WM_MOUSEFIRST 0x200
#define WM_MOUSEMOVE 0x200
#define WM_LBUTTONDOWN 0x201
#define WM_LBUTTONUP 0x202
#define WM_LBUTTONDBLCLK 0x203
#define WM_RBUTTONDOWN 0x204
#define WM_RBUTTONUP 0x205
#define WM_RBUTTONDBLCLK 0x206
#define WM_MBUTTONDOWN 0x207
#define WM_MBUTTONUP 0x208
#define WM_MBUTTONDBLCLK 0x209
#define WM_MOUSEWHEEL 0x20A
#define WM_XBUTTONDOWN 0x20B
#define WM_XBUTTONUP 0x20C
#define WM_XBUTTONDBLCLK 0x20D
#define WM_MOUSEHWHEEL 0x20e

#define GET_X_LPARAM(X) ((int)(short)LOWORD(X))
#define GET_Y_LPARAM(X) ((int)(short)HIWORD(X))

#define WHEEL_DELTA 120
#define GET_WHEEL_DELTA_WPARAM(X) ((short)HIWORD(X))

typedef struct tagMSG {
	HWND   hwnd;
	UINT   message;
	WPARAM wParam;
	LPARAM lParam;
	DWORD  time;
	POINT  pt;
} MSG, *PMSG, *LPMSG;

typedef struct tagCREATESTRUCT {
  LPVOID    lpCreateParams;
  HINSTANCE hInstance;
  HMENU     hMenu;
  HWND      hwndParent;
  int       cy;
  int       cx;
  int       y;
  int       x;
  LONG      style;
  LPCTSTR   lpszName;
  LPCTSTR   lpszClass;
  DWORD     dwExStyle;
} CREATESTRUCT, *LPCREATESTRUCT;

typedef struct tagWNDCLASSEX {
  UINT      cbSize;
  UINT      style;
  WNDPROC   lpfnWndProc;
  int       cbClsExtra;
  int       cbWndExtra;
  HINSTANCE hInstance;
  HICON     hIcon;
  HCURSOR   hCursor;
  HBRUSH    hbrBackground;
  LPCTSTR   lpszMenuName;
  LPCTSTR   lpszClassName;
  HICON     hIconSm;
} WNDCLASSEX, *PWNDCLASSEX;

HCURSOR WINAPI LoadCursor(HINSTANCE hInstance, LPCTSTR lpCursorName);

int WINAPI MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);

ATOM WINAPI RegisterClassEx(const WNDCLASSEX *lpwcx);

LONG_PTR WINAPI SetWindowLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLong);

LONG_PTR WINAPI GetWindowLongPtr(HWND hWnd, int nIndex);

LRESULT WINAPI DefWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

BOOL WINAPI ValidateRect(HWND hWnd, const RECT *lpRect);

HDC WINAPI GetDC(HWND hWnd);

int WINAPI ReleaseDC(HWND hWnd, HDC hDC);

BOOL WINAPI AdjustWindowRect(RECT *lpRect, DWORD dwStyle, BOOL bMenu);

HWND WINAPI CreateWindowEx(DWORD dwExStyle,
	LPCTSTR   lpClassName,
	LPCTSTR   lpWindowName,
	DWORD     dwStyle,
	int       x,
	int       y,
	int       nWidth,
	int       nHeight,
	HWND      hWndParent,
	HMENU     hMenu,
	HINSTANCE hInstance,
	LPVOID    lpParam);

BOOL WINAPI PeekMessage( LPMSG lpMsg,
	HWND  hWnd,
	UINT  wMsgFilterMin,
	UINT  wMsgFilterMax,
	UINT  wRemoveMsg);

BOOL WINAPI TranslateMessage(const MSG *lpMsg);

LRESULT WINAPI DispatchMessage(const MSG *lpmsg);

BOOL WINAPI DestroyWindow(HWND hWnd);

BOOL WINAPI ShowWindow(HWND hWnd, int nCmdShow);

HMODULE WINAPI GetModuleHandle(LPCTSTR lpModuleName);

FARPROC WINAPI GetProcAddress(HMODULE hModule, LPCSTR lpProcName);

int WINAPI ShowCursor(BOOL bShow);

BOOL WINAPI GetClientRect(HWND hWnd, LPRECT lpRect);

BOOL WINAPI WaitMessage(void);

#endif
